import { Op } from 'sequelize';
import Role from '@/models/system/role.model';
import Menu from '@/models/system/menu.model';
import User from '@/models/system/user.model';
import UserRole from '@/models/system/userRole.model';
import RoleMenu from '@/models/system/roleMenu.model';
import RoleDept from '@/models/system/roleDept.model';
import sequelize from '@/config/database';
import { getLogger } from '@/utils/logger';
import Dept from '@/models/system/dept.model';

// 创建模块专用的日志记录器
const consoleLogger = getLogger("role-service");
const logger = getLogger("role-service", {
	console: false,
});

// 查询参数接口
export interface RoleQueryParams {
  roleName?: string;
  roleKey?: string;
  status?: string;
  beginTime?: string;
  endTime?: string;
  pageNum?: number;
  pageSize?: number;
}

// 用户查询参数接口
export interface UserQueryParams {
  userName?: string;
  phonenumber?: string;
  status?: string;
  pageNum?: number;
  pageSize?: number;
}

class RoleService {
  /**
   * 根据条件分页查询角色数据
   * @param params 查询参数
   * @param pageNum 页码
   * @param pageSize 每页条数
   */
  async listRolesByPage(params: any, pageNum: number, pageSize: number) {
    try {
      const { roleName, roleKey, status, beginTime, endTime } = params;
      
      // 记录查询开始
      consoleLogger.info(`开始查询角色列表: 页码=${pageNum}, 每页=${pageSize}${roleName ? ', 角色名=' + roleName : ''}${roleKey ? ', 权限标识=' + roleKey : ''}${status ? ', 状态=' + status : ''}`);
      
      const where: any = {};
      if (roleName) {
        where.roleName = { [Op.like]: `%${roleName}%` };
      }
      if (roleKey) {
        where.roleKey = { [Op.like]: `%${roleKey}%` };
      }
      if (status) {
        where.status = status;
      }
      if (beginTime && endTime) {
        where.createTime = { [Op.between]: [beginTime, endTime] };
      }
      where.delFlag = '0';

      // 构建查询选项
      const options: any = {
        where,
        order: [['roleSort', 'ASC']]
      };
      
      // 如果pageSize大于0，则进行分页
      if (pageSize > 0) {
        options.offset = (pageNum - 1) * pageSize;
        options.limit = pageSize;
      }

      const { count, rows } = await Role.findAndCountAll(options);

      // 为每个角色设置必要的属性
      for (const role of rows) {
        // 导出数据时不需要获取关联数据，只设置默认值即可
        role.menuIds = [];
        role.deptIds = [];
        role.permissions = [];
        role.flag = false;
      }

      // 记录查询结果
      logger.info(`角色列表查询完成: 总数=${count}, 页码=${pageNum}, 每页=${pageSize}`);
      
      return {
        total: count,
        rows
      };
    } catch (error) {
      consoleLogger.error(`查询角色列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('查询角色列表失败');
    }
  }

  /**
   * 根据用户ID查询角色
   * @param userId 用户ID
   */
  async getRolesByUserId(userId: number) {
    try {
      // 记录操作开始
      consoleLogger.info(`查询用户角色: userId=${userId}`);
      
      // 查询用户拥有的所有角色
      const userRoles = await User.findByPk(userId, {
        include: [{
          model: Role,
          through: { attributes: [] },
          where: { delFlag: '0' }
        }]
      });

      const roles = userRoles?.get('Roles') || [];
      
      // 为每个角色获取关联的菜单ID、部门ID和权限
      if (Array.isArray(roles)) {
        for (const role of roles) {
          role.menuIds = await this.getRoleMenuIds(role.roleId);
          role.deptIds = await this.getRoleDeptIds(role.roleId);
          role.permissions = await this.getRolePermissions(role.roleId);
          role.flag = true; // 用户拥有的角色，flag设为true
        }
      }
      
      // 记录查询结果
      logger.info(`用户角色查询完成: userId=${userId}, 角色数量=${Array.isArray(roles) ? roles.length : 0}`);
      
      return Array.isArray(roles) ? roles : [];
    } catch (error) {
      consoleLogger.error(`根据用户ID查询角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        userId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return [];
    }
  }

  /**
   * 查询所有角色
   */
  async selectRoleAll() {
    try {
      // 记录操作开始
      consoleLogger.info('查询所有角色');
      
      const roles = await Role.findAll({
        where: { delFlag: '0' },
        order: [['roleSort', 'ASC']]
      });
      
      // 为每个角色获取关联的菜单ID、部门ID和权限
      for (const role of roles) {
        role.menuIds = await this.getRoleMenuIds(role.roleId);
        role.deptIds = await this.getRoleDeptIds(role.roleId);
        role.permissions = await this.getRolePermissions(role.roleId);
        role.flag = false; // 设置默认值
      }
      
      // 记录查询结果
      logger.info(`查询所有角色完成: 角色数量=${roles.length}`);
      
      return roles;
    } catch (error) {
      consoleLogger.error(`查询所有角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('查询所有角色失败');
    }
  }

  /**
   * 根据角色ID查询角色
   * @param roleId 角色ID
   */
  async selectRoleById(roleId: number) {
    try {
      // 记录操作开始
      consoleLogger.info(`根据ID查询角色: roleId=${roleId}`);
      
      // 确保 roleId 是有效的数字
      if (isNaN(Number(roleId))) {
        consoleLogger.warn(`无效的角色ID: ${roleId}`);
        return null;
      }
      
      const role = await Role.findByPk(Number(roleId));
      
      if (!role) {
        consoleLogger.warn(`角色不存在: roleId=${roleId}`);
        return null;
      }
      
      // 获取角色关联的菜单ID列表
      // role.menuIds = await this.getRoleMenuIds(roleId);
      role.menuIds = null;
      
      // 获取角色关联的部门ID列表
      // role.deptIds = await this.getRoleDeptIds(roleId);
      role.deptIds = null;
      
      // 获取角色权限
      // role.permissions = await this.getRolePermissions(roleId);
      role.permissions = null;
      
      // 设置flag默认值
      role.flag = false;
      
      // 记录查询结果
      logger.info(`根据ID查询角色完成: roleId=${roleId}, 角色名=${role.roleName}`);
      
      return role;
    } catch (error) {
      consoleLogger.error(`根据ID查询角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return null;
    }
  }

  /**
   * 获取角色的权限列表
   * @param roleId 角色ID
   */
  async getRolePermissions(roleId: number): Promise<string[]> {
    try {
      // 记录操作开始
      consoleLogger.info(`获取角色权限列表: roleId=${roleId}`);
      
      // 查询角色关联的菜单ID
      const roleMenus = await RoleMenu.findAll({
        where: { roleId },
        attributes: ['menuId']
      });
      
      if (roleMenus.length === 0) {
        logger.debug(`角色没有关联菜单: roleId=${roleId}`);
        return [];
      }
      
      // 获取菜单ID列表
      const menuIds = roleMenus.map(rm => rm.menuId);
      
      // 查询这些菜单的权限
      const menus = await Menu.findAll({
        where: {
          menuId: { [Op.in]: menuIds },
          status: '0'
        },
        attributes: ['perms']
      });
      
      // 提取权限标识
      const permissions: string[] = [];
      
      menus.forEach(menu => {
        const perms = menu.perms;
        if (perms && perms.trim() !== '') {
          perms.split(',').forEach(perm => {
            const trimmedPerm = perm.trim();
            if (trimmedPerm !== '' && !permissions.includes(trimmedPerm)) {
              permissions.push(trimmedPerm);
            }
          });
        }
      });
      
      // 记录查询结果
      logger.debug(`角色权限列表查询完成: roleId=${roleId}, 权限数量=${permissions.length}`);
      
      return permissions;
    } catch (error) {
      consoleLogger.error(`获取角色权限列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return [];
    }
  }

  /**
   * 校验角色名称是否唯一
   * @param roleName 角色名称
   * @param roleId 角色ID
   */
  async checkRoleNameUnique(roleName: string, roleId?: number) {
    try {
      consoleLogger.info(`校验角色名称唯一性: roleName=${roleName}${roleId ? ', roleId=' + roleId : ''}`);
      
      const where: any = { roleName, delFlag: '0' };
      if (roleId) {
        where.roleId = { [Op.ne]: roleId };
      }
      const role = await Role.findOne({ where });
      
      const isUnique = !role;
      logger.info(`角色名称唯一性校验结果: roleName=${roleName}, 是否唯一=${isUnique}`);
      
      return isUnique;
    } catch (error) {
      consoleLogger.error(`校验角色名称唯一性失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleName,
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return false;
    }
  }

  /**
   * 校验角色权限是否唯一
   * @param roleKey 角色权限
   * @param roleId 角色ID
   */
  async checkRoleKeyUnique(roleKey: string, roleId?: number) {
    try {
      consoleLogger.info(`校验角色权限唯一性: roleKey=${roleKey}${roleId ? ', roleId=' + roleId : ''}`);
      
      const where: any = { roleKey, delFlag: '0' };
      if (roleId) {
        where.roleId = { [Op.ne]: roleId };
      }
      const role = await Role.findOne({ where });
      
      const isUnique = !role;
      logger.info(`角色权限唯一性校验结果: roleKey=${roleKey}, 是否唯一=${isUnique}`);
      
      return isUnique;
    } catch (error) {
      consoleLogger.error(`校验角色权限唯一性失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleKey,
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return false;
    }
  }

  /**
   * 校验角色是否允许操作
   * @param role 角色信息
   */
  checkRoleAllowed(role: Role) {
    try {
      consoleLogger.info(`校验角色是否允许操作: roleId=${role.roleId}, roleKey=${role.roleKey}`);
      
      if (role.isAdmin()) {
        consoleLogger.warn(`尝试操作超级管理员角色: roleId=${role.roleId}`);
        throw new Error('不允许操作超级管理员角色');
      }
      
      logger.info(`角色允许操作: roleId=${role.roleId}`);
      return true;
    } catch (error) {
      consoleLogger.error(`校验角色是否允许操作失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId: role.roleId,
        roleKey: role.roleKey,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw error;
    }
  }

  /**
   * 通过角色ID查询角色使用数量
   * @param roleId 角色ID
   */
  async countUserRoleByRoleId(roleId: number) {
    try {
      consoleLogger.info(`查询角色使用数量: roleId=${roleId}`);
      
      const count = await UserRole.count({ where: { roleId } });
      
      logger.info(`角色使用数量查询完成: roleId=${roleId}, 数量=${count}`);
      
      return count;
    } catch (error) {
      consoleLogger.error(`查询角色使用数量失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return 0;
    }
  }

  /**
   * 新增保存角色信息
   * @param role 角色信息
   */
  async insertRole(role: any) {
    // 开启事务
    const transaction = await sequelize.transaction();
    try {
      // 记录操作开始
      consoleLogger.info(`新增角色: ${role.roleName}, 操作人: ${role.createBy || 'unknown'}`);
      
      // 新增角色信息
      const newRole = await Role.create(role, { transaction });
      
      // 新增角色菜单关联
      if (role.menuIds && role.menuIds.length > 0) {
        const roleMenus = role.menuIds.map((menuId: number) => ({
          roleId: newRole.roleId,
          menuId
        }));
        await RoleMenu.bulkCreate(roleMenus, { transaction });
        
        // 记录菜单关联
        logger.info(`角色菜单关联创建成功: roleId=${newRole.roleId}, 菜单数量=${role.menuIds.length}`);
      }
      
      await transaction.commit();
      
      // 设置menuIds属性
      newRole.menuIds = role.menuIds || null;
      
      // 设置permissions和flag属性
      newRole.permissions = await this.getRolePermissions(newRole.roleId);
      newRole.flag = false;
      
      // 记录操作完成
      logger.info(`新增角色成功: roleId=${newRole.roleId}, roleName=${newRole.roleName}`);
      
      return newRole;
    } catch (error) {
      await transaction.rollback();
      consoleLogger.error(`新增角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        role: {
          roleName: role.roleName,
          roleKey: role.roleKey
        },
        stack: error instanceof Error ? error.stack : undefined
      });
      throw error;
    }
  }

  /**
   * 修改保存角色信息
   * @param role 角色信息
   */
  async updateRole(role: any) {
    // 开启事务
    const transaction = await sequelize.transaction();
    try {
      // 记录操作开始
      consoleLogger.info(`修改角色: roleId=${role.roleId}, roleName=${role.roleName}, 操作人: ${role.updateBy || 'unknown'}`);
      
      // 修改角色信息
      const roleId = role.roleId;
      await Role.update(role, { 
        where: { roleId },
        transaction 
      });
      
      // 删除角色与菜单关联
      await RoleMenu.destroy({
        where: { roleId },
        transaction
      });

      // 新增角色菜单关联
      if (role.menuIds && role.menuIds.length > 0) {
        const roleMenus = role.menuIds.map((menuId: number) => ({
          roleId,
          menuId
        }));
        await RoleMenu.bulkCreate(roleMenus, { transaction });
        
        // 记录菜单关联
        logger.info(`角色菜单关联更新成功: roleId=${roleId}, 菜单数量=${role.menuIds.length}`);
      }
      
      await transaction.commit();
      
      // 查询更新后的角色
      const updatedRole = await this.selectRoleById(roleId);
      
      // 记录操作完成
      logger.info(`修改角色成功: roleId=${roleId}`);
      
      return updatedRole;
    } catch (error) {
      await transaction.rollback();
      consoleLogger.error(`修改角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId: role.roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw error;
    }
  }

  /**
   * 批量删除角色信息
   * @param roleIds 角色ID数组
   */
  async deleteRoleByIds(roleIds: number[]) {
    // 开启事务
    const transaction = await sequelize.transaction();
    try {
      // 记录操作开始
      consoleLogger.info(`批量删除角色: roleIds=${roleIds.join(',')}`);
      
      // 查询角色是否存在用户
      const userCount = await UserRole.count({
        where: { roleId: { [Op.in]: roleIds } }
      });
      if (userCount > 0) {
        consoleLogger.warn(`角色已分配给用户，不能删除: roleIds=${roleIds.join(',')}, 用户数=${userCount}`);
        throw new Error('角色已分配，不能删除');
      }

      // 查询角色是否为管理员
      const adminRoles = await Role.findAll({
        where: {
          roleId: { [Op.in]: roleIds },
          roleKey: 'admin'
        }
      });
      if (adminRoles.length > 0) {
        const adminRoleIds = adminRoles.map(role => role.roleId).join(',');
        consoleLogger.warn(`尝试删除超级管理员角色: roleIds=${adminRoleIds}`);
        throw new Error('不允许删除超级管理员角色');
      }

      // 删除角色与菜单关联
      await RoleMenu.destroy({
        where: { roleId: { [Op.in]: roleIds } },
        transaction
      });
      logger.info(`删除角色菜单关联成功: roleIds=${roleIds.join(',')}`);

      // 删除角色与部门关联
      await RoleDept.destroy({
        where: { roleId: { [Op.in]: roleIds } },
        transaction
      });
      logger.info(`删除角色部门关联成功: roleIds=${roleIds.join(',')}`);

      // 删除角色
      await Role.update(
        { delFlag: '2' },
        { 
          where: { roleId: { [Op.in]: roleIds } },
          transaction 
        }
      );
      
      await transaction.commit();
      
      // 记录操作完成
      logger.info(`批量删除角色成功: roleIds=${roleIds.join(',')}`);
      
      return true;
    } catch (error) {
      await transaction.rollback();
      consoleLogger.error(`批量删除角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleIds,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw error;
    }
  }

  /**
   * 检查用户是否具有特定权限
   * @param userId 用户ID
   * @param permission 权限标识
   */
  async hasPermission(userId: number, permission: string): Promise<boolean> {
    try {
      // 记录操作开始
      consoleLogger.info(`检查用户权限: userId=${userId}, permission=${permission}`);
      
      // 查询用户角色
      const roles = await this.getRolesByUserId(userId);
      
      // 超级管理员拥有所有权限
      if (Array.isArray(roles) && roles.some((role: any) => role.roleKey === 'admin')) {
        logger.info(`用户是超级管理员，拥有所有权限: userId=${userId}`);
        return true;
      }

      // 查询角色关联的菜单权限
      const roleIds = Array.isArray(roles) ? roles.map((role: any) => role.roleId) : [];
      const menus = await Menu.findAll({
        include: [{
          model: Role,
          through: { attributes: [] },
          where: { roleId: { [Op.in]: roleIds } }
        }],
        where: {
          perms: permission,
          status: '0'
        }
      });

      const hasPermission = menus.length > 0;
      
      // 记录检查结果
      logger.info(`用户权限检查完成: userId=${userId}, permission=${permission}, 结果=${hasPermission}`);
      
      return hasPermission;
    } catch (error) {
      consoleLogger.error(`检查用户权限失败: ${error instanceof Error ? error.message : String(error)}`, {
        userId,
        permission,
        stack: error instanceof Error ? error.stack : undefined
      });
      return false;
    }
  }

  /**
   * 获取用户的数据权限范围
   * @param userId 用户ID
   */
  async getUserDataScope(userId: number): Promise<string[]> {
    try {
      // 记录操作开始
      consoleLogger.info(`获取用户数据权限范围: userId=${userId}`);
      
      // 查询用户角色
      const roles = await this.getRolesByUserId(userId);
      
      // 超级管理员拥有所有数据权限
      if (Array.isArray(roles) && roles.some((role: any) => role.roleKey === 'admin')) {
        logger.info(`用户是超级管理员，拥有全部数据权限: userId=${userId}`);
        return ['1']; // 全部数据权限
      }

      // 获取角色的数据权限范围
      const dataScopes: string[] = Array.isArray(roles) 
        ? roles.map((role: any) => role.dataScope).filter((scope): scope is string => typeof scope === 'string')
        : [];
      
      // 去重返回
      const uniqueScopes = [...new Set(dataScopes)];
      
      // 记录查询结果
      logger.info(`用户数据权限范围查询完成: userId=${userId}, 权限范围=${uniqueScopes.join(',')}`);
      
      return uniqueScopes;
    } catch (error) {
      consoleLogger.error(`获取用户数据权限范围失败: ${error instanceof Error ? error.message : String(error)}`, {
        userId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return [];
    }
  }

  /**
   * 查询已分配用户角色列表
   * @param params 查询参数
   * @param roleId 角色ID
   */
  async getAllocatedUserList(params: UserQueryParams, roleId: number) {
    try {
      const { pageNum = 1, pageSize = 10, userName, phonenumber, status } = params;
      
      // 记录操作开始
      consoleLogger.info(`查询已分配用户角色列表: roleId=${roleId}, 页码=${pageNum}, 每页=${pageSize}${userName ? ', 用户名=' + userName : ''}${phonenumber ? ', 手机号=' + phonenumber : ''}${status ? ', 状态=' + status : ''}`);
      
      // 构建查询条件
      const whereConditions: any = {
        delFlag: '0'
      };
      
      if (userName) {
        whereConditions.userName = { [Op.like]: `%${userName}%` };
      }
      
      if (phonenumber) {
        whereConditions.phonenumber = { [Op.like]: `%${phonenumber}%` };
      }
      
      if (status) {
        whereConditions.status = status;
      }
      
      // 查询已分配指定角色的用户
      const { count, rows } = await User.findAndCountAll({
        where: whereConditions,
        include: [
          {
            model: Role,
            as: 'roles',
            where: { roleId, delFlag: '0' },
            through: { attributes: [] },
            required: true
          },
          {
            model: Dept,
            as: 'dept',
            attributes: ['deptName'],
            required: false
          }
        ],
        attributes: { exclude: ['password'] },
        offset: (Number(pageNum) - 1) * Number(pageSize),
        limit: Number(pageSize),
        distinct: true,
        order: [['createTime', 'DESC']]
      });
      
      // 格式化返回数据
      const formattedRows = rows.map((user: any) => {
        const plainUser = user.get({ plain: true });
        return {
          ...plainUser,
          dept_name: plainUser.dept?.deptName || ''
        };
      });
      
      // 记录查询结果
      logger.info(`已分配用户角色列表查询完成: roleId=${roleId}, 总数=${count}, 页码=${pageNum}, 每页=${pageSize}`);
      
      return {
        total: count,
        rows: formattedRows,
        pageNum: Number(pageNum),
        pageSize: Number(pageSize)
      };
    } catch (error) {
      consoleLogger.error(`查询已分配用户角色列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        params,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('查询已分配用户角色列表失败');
    }
  }
  
  /**
   * 查询未分配用户角色列表
   * @param params 查询参数
   * @param roleId 角色ID
   */
  async getUnallocatedUserList(params: UserQueryParams, roleId: number) {
    try {
      const { pageNum = 1, pageSize = 10, userName, phonenumber, status } = params;
      
      // 记录操作开始
      consoleLogger.info(`查询未分配用户角色列表: roleId=${roleId}, 页码=${pageNum}, 每页=${pageSize}${userName ? ', 用户名=' + userName : ''}${phonenumber ? ', 手机号=' + phonenumber : ''}${status ? ', 状态=' + status : ''}`);
      
      // 构建查询条件
      const whereConditions: any = {
        delFlag: '0'
      };
      
      if (userName) {
        whereConditions.userName = { [Op.like]: `%${userName}%` };
      }
      
      if (phonenumber) {
        whereConditions.phonenumber = { [Op.like]: `%${phonenumber}%` };
      }
      
      if (status) {
        whereConditions.status = status;
      }
      
      // 查找已分配该角色的用户ID
      const assignedUserIds = await UserRole.findAll({
        where: { roleId },
        attributes: ['userId']
      }).then(results => results.map(item => item.userId));
      
      // 如果有已分配的用户，则排除这些用户
      if (assignedUserIds.length > 0) {
        whereConditions.userId = {
          [Op.notIn]: assignedUserIds
        };
        logger.debug(`排除已分配角色的用户: roleId=${roleId}, 已分配用户数=${assignedUserIds.length}`);
      }
      
      // 查询未分配指定角色的用户
      const { count, rows } = await User.findAndCountAll({
        where: whereConditions,
        include: [
          {
            model: Dept,
            as: 'dept',
            attributes: ['deptName'],
            required: false
          }
        ],
        attributes: { exclude: ['password'] },
        offset: (Number(pageNum) - 1) * Number(pageSize),
        limit: Number(pageSize),
        order: [['createTime', 'DESC']]
      });
      
      // 格式化返回数据
      const formattedRows = rows.map((user: any) => {
        const plainUser = user.get({ plain: true });
        return {
          ...plainUser,
          dept_name: plainUser.dept?.deptName || ''
        };
      });
      
      // 记录查询结果
      logger.info(`未分配用户角色列表查询完成: roleId=${roleId}, 总数=${count}, 页码=${pageNum}, 每页=${pageSize}`);
      
      return {
        total: count,
        rows: formattedRows,
        pageNum: Number(pageNum),
        pageSize: Number(pageSize)
      };
    } catch (error) {
      consoleLogger.error(`查询未分配用户角色列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        params,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('查询未分配用户角色列表失败');
    }
  }
  
  /**
   * 授权用户角色
   * @param roleId 角色ID
   * @param userIds 用户ID数组
   * @param operator 操作人
   */
  async authorizeUserRole(roleId: number, userIds: number[], operator: string) {
    const transaction = await sequelize.transaction();
    try {
      // 记录操作开始
      consoleLogger.info(`授权用户角色: roleId=${roleId}, userIds=${userIds.join(',')}, 操作人=${operator}`);
      
      // 检查角色是否存在
      const role = await Role.findByPk(roleId, { transaction });
      if (!role) {
        consoleLogger.warn(`授权失败，角色不存在: roleId=${roleId}`);
        throw new Error('角色不存在');
      }
      
      // 构建用户角色关联数据
      const userRoles = userIds.map(userId => ({
        userId,
        roleId
      }));
      
      // 批量创建用户角色关联
      await UserRole.bulkCreate(userRoles, { 
        transaction,
        ignoreDuplicates: true // 忽略重复数据
      });
      
      await transaction.commit();
      
      // 记录操作完成
      logger.info(`授权用户角色成功: roleId=${roleId}, 用户数量=${userIds.length}, 操作人=${operator}`);
      
      return true;
    } catch (error) {
      await transaction.rollback();
      consoleLogger.error(`授权用户角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        userIds,
        operator,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('授权用户角色失败');
    }
  }
  
  /**
   * 取消授权用户角色
   * @param roleId 角色ID
   * @param userId 用户ID
   */
  async cancelUserRoleAuthorization(roleId: number, userId: number) {
    try {
      // 记录操作开始
      consoleLogger.info(`取消授权用户角色: roleId=${roleId}, userId=${userId}`);
      
      // 删除用户角色关联
      const result = await UserRole.destroy({
        where: {
          roleId,
          userId
        }
      });
      
      const success = result > 0;
      
      // 记录操作结果
      if (success) {
        logger.info(`取消授权用户角色成功: roleId=${roleId}, userId=${userId}`);
      } else {
        logger.warn(`取消授权用户角色无效: roleId=${roleId}, userId=${userId}, 可能关联不存在`);
      }
      
      return success;
    } catch (error) {
      consoleLogger.error(`取消授权用户角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        userId,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('取消授权用户角色失败');
    }
  }
  
  /**
   * 批量取消授权用户角色
   * @param roleId 角色ID
   * @param userIds 用户ID数组
   */
  async cancelUserRoleAuthorizationBatch(roleId: number, userIds: number[]) {
    try {
      // 记录操作开始
      consoleLogger.info(`批量取消授权用户角色: roleId=${roleId}, userIds=${userIds.join(',')}`);
      
      // 批量删除用户角色关联
      const result = await UserRole.destroy({
        where: {
          roleId,
          userId: {
            [Op.in]: userIds
          }
        }
      });
      
      const success = result > 0;
      
      // 记录操作结果
      if (success) {
        logger.info(`批量取消授权用户角色成功: roleId=${roleId}, 用户数量=${userIds.length}, 实际删除数量=${result}`);
      } else {
        logger.warn(`批量取消授权用户角色无效: roleId=${roleId}, userIds=${userIds.join(',')}, 可能关联不存在`);
      }
      
      return success;
    } catch (error) {
      consoleLogger.error(`批量取消授权用户角色失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        userIds,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('批量取消授权用户角色失败');
    }
  }
  
  /**
   * 更新角色数据权限
   * @param role 角色信息，包含roleId, dataScope, deptCheckStrictly, deptIds
   * @param operator 操作人
   */
  async updateRoleDataScope(role: any, operator: string) {
    const transaction = await sequelize.transaction();
    try {
      // 记录操作开始
      consoleLogger.info(`更新角色数据权限: roleId=${role.roleId}, dataScope=${role.dataScope}, 操作人=${operator}`);
      
      // 修改角色信息
      const roleId = role.roleId;
      await Role.update(
        {
          dataScope: role.dataScope,
          deptCheckStrictly: role.deptCheckStrictly,
          updateBy: operator,
          updateTime: new Date()
        },
        {
          where: { roleId },
          transaction
        }
      );
      
      // 删除角色与部门关联
      await RoleDept.destroy({
        where: { roleId },
        transaction
      });
      
      // 新增角色部门关联
      if (role.deptIds && role.deptIds.length > 0) {
        const roleDepts = role.deptIds.map((deptId: number) => ({
          roleId,
          deptId
        }));
        await RoleDept.bulkCreate(roleDepts, { transaction });
        
        // 记录部门关联
        logger.info(`角色部门关联更新成功: roleId=${roleId}, 部门数量=${role.deptIds.length}`);
      }
      
      await transaction.commit();
      
      // 查询更新后的角色
      const updatedRole = await this.selectRoleById(roleId);
      
      // 记录操作完成
      logger.info(`更新角色数据权限成功: roleId=${roleId}, dataScope=${role.dataScope}`);
      
      return updatedRole;
    } catch (error) {
      await transaction.rollback();
      consoleLogger.error(`修改角色数据权限失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId: role.roleId,
        dataScope: role.dataScope,
        operator,
        stack: error instanceof Error ? error.stack : undefined
      });
      throw new Error('修改角色数据权限失败');
    }
  }

  /**
   * 获取角色关联的菜单ID列表
   * @param roleId 角色ID
   */
  async getRoleMenuIds(roleId: number): Promise<number[]> {
    try {
      // 记录操作开始
      consoleLogger.info(`获取角色菜单ID列表: roleId=${roleId}`);
      
      const roleMenus = await RoleMenu.findAll({
        where: { roleId },
        attributes: ['menuId']
      });
      
      const menuIds = roleMenus.map(item => Number(item.get('menuId')));
      
      // 记录查询结果
      logger.debug(`角色菜单ID列表查询完成: roleId=${roleId}, 菜单数量=${menuIds.length}`);
      
      return menuIds;
    } catch (error) {
      consoleLogger.error(`获取角色菜单ID列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return [];
    }
  }

  /**
   * 获取角色关联的部门ID列表
   * @param roleId 角色ID
   */
  async getRoleDeptIds(roleId: number): Promise<number[]> {
    try {
      // 记录操作开始
      consoleLogger.info(`获取角色部门ID列表: roleId=${roleId}`);
      
      const roleDepts = await RoleDept.findAll({
        where: { roleId },
        attributes: ['deptId']
      });
      
      const deptIds = roleDepts.map(item => Number(item.get('deptId')));
      
      // 记录查询结果
      logger.debug(`角色部门ID列表查询完成: roleId=${roleId}, 部门数量=${deptIds.length}`);
      
      return deptIds;
    } catch (error) {
      consoleLogger.error(`获取角色部门ID列表失败: ${error instanceof Error ? error.message : String(error)}`, {
        roleId,
        stack: error instanceof Error ? error.stack : undefined
      });
      return [];
    }
  }
}

export default new RoleService();